"use strict";

/**
 * @fileoverview style 插件
 */
function style() {
  this.styles = [];
} // #ifndef APP-PLUS-NVUE


var parser = require('./parser');

style.prototype.onParse = function (node, vm) {
  // 获取样式
  if (node.name == 'style' && node.children.length && node.children[0].type == 'text') {
    this.styles = this.styles.concat(new parser().parse(node.children[0].text));
  } // 匹配样式（对非文本标签）
  else if (node.name) {
      // 存储不同优先级的样式 name < class < id < 后代
      var matched = ['', '', '', ''];

      for (var i = 0, len = this.styles.length; i < len; i++) {
        var item = this.styles[i],
            j,
            res = match(node, item.key || item.list[item.list.length - 1]);

        if (res) {
          // 后代选择器
          if (!item.key) {
            j = item.list.length - 2;

            for (var k = vm.stack.length; j >= 0 && k--;) {
              // 子选择器
              if (item.list[j] == '>') {
                // 错误情况
                if (j < 1 || j > item.list.length - 2) break;
                if (match(vm.stack[k], item.list[j - 1])) j -= 2;else j++;
              } else if (match(vm.stack[k], item.list[j])) j--;
            }

            res = 4;
          }

          if (item.key || j < 0) {
            // 添加伪类
            if (item.pseudo && node.children) {
              var text;
              item.style = item.style.replace(/content:([^;]+)/, function (_, $1) {
                text = $1.replace(/['"]/g, '') // 处理 attr 函数
                .replace(/attr\((.+?)\)/, function (_, $1) {
                  return node.attrs[$1.trim()] || '';
                }) // 编码 \xxx
                .replace(/\\(\w{4})/, function (_, $1) {
                  return String.fromCharCode(parseInt($1, 16));
                });
                return '';
              });
              var pseudo = {
                name: 'span',
                attrs: {
                  style: item.style
                },
                children: [{
                  type: 'text',
                  text: text
                }]
              };
              if (item.pseudo == 'before') node.children.unshift(pseudo);else node.children.push(pseudo);
            } else matched[res - 1] += item.style + (item.style[item.style.length - 1] == ';' ? '' : ';');
          }
        }
      }

      matched = matched.join('');
      if (matched.length > 2) node.attrs.style = matched + (node.attrs.style || '');
    }
};
/**
 * @description 匹配样式
 * @param {object} node 要匹配的标签
 * @param {string|string[]} keys 选择器
 * @returns {number} 0：不匹配；1：name 匹配；2：class 匹配；3：id 匹配
 */


function match(node, keys) {
  function matchItem(key) {
    // 匹配 id
    if (key[0] == '#') {
      if (node.attrs.id && node.attrs.id.trim() == key.substr(1)) return 3;
    } // 匹配 class
    else if (key[0] == '.') {
        key = key.substr(1);
        var selectors = (node.attrs["class"] || '').split(' ');

        for (var i = 0; i < selectors.length; i++) {
          if (selectors[i].trim() == key) return 2;
        }
      } // 匹配 name
      else if (node.name == key) return 1;

    return 0;
  } // 多选择器交集


  if (keys instanceof Array) {
    var res = 0;

    for (var j = 0; j < keys.length; j++) {
      var tmp = matchItem(keys[j]); // 任意一个不匹配就失败

      if (!tmp) return 0; // 优先级最大的一个作为最终优先级

      if (tmp > res) res = tmp;
    }

    return res;
  }

  return matchItem(keys);
} // #endif


module.exports = style;